iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
Modern Web

給心理人的前端網頁開發系列 第 23

[給心理人的前端網頁開發] 23 關卡三:網路實驗 - jsPsych Demo Simple Reaction Time Task 解釋

  • 分享至 

  • xImage
  •  

昨天展示了,如何把 Demo 的實驗給 run 起來,今天來講解實驗流程大概有哪些東西,以及這程式碼做了些什麼事情。主要以註解的方式呈現。

一、實驗流程

通常一個實驗流程,多少會有以下這些階段

  1. 歡迎資訊
  2. 指導語
  3. 練習階段
  4. 正式階段
  5. 結束語

歡迎資訊,會簡單歡迎一下受試者。可能會說一下主試者的背景,以及這個實驗的名稱(也可能不會,怕受試者會有預期效果)

指導語,會說一下這個實驗大概在做什麼主題、想知道什麼事情。受試者需要做哪些事情,以及注意事項。

練習階段,先讓受試者熟悉一下等等要要什麼事情。基本上會跟正式階段要作的事情一樣,只是要做的題數會比較少。通常每一題會被叫做一個嘗試次(trial)。通常一個嘗試次可能會兩個部分組成:凝視的頁面、跟呈現刺激材料的頁面。

凝視的頁面,常常會是一個黑色的小十字。這是為了讓受試者將注意力放在螢幕的中間,減少實驗的變因。等到一段時間後,螢幕畫面會自動變成呈現刺激材料的頁面。受試者看到刺激材料後,就要透過按鍵盡量且快速地做出正確的回答。

正式階段,就是實驗設計者主要收集資訊的階段。實驗設計的獨變項,會在許多嘗試次中用不同的方式呈現出來。

以上是常見的,透過電腦軟體來進行的心理學實驗流程。心理學的實驗設計與流程絕對不只這一種,只是剛好 demo 的程式剛好符合這個流程,所以拿出來當作說明。

接下來透過註解的方式,來說明程式的結構跟心理實驗流程有很多可以對應的地方。

二、程式講解

<!DOCTYPE html>
<html>
  <head>
    <title>My experiment</title>

		<!-- 引入運行 jspsych 需要的程式碼套件 -->
    <script src="https://unpkg.com/jspsych@7.3.3"></script>
    <script src="https://unpkg.com/@jspsych/plugin-html-keyboard-response@1.1.2"></script>
    <script src="https://unpkg.com/@jspsych/plugin-image-keyboard-response@1.1.2"></script>
    <script src="https://unpkg.com/@jspsych/plugin-preload@1.1.2"></script>
    <link href="https://unpkg.com/jspsych@7.3.3/css/jspsych.css" rel="stylesheet" type="text/css" />
  </head>
  <body></body>
  <script>

    /** 
     * initialize jsPsych
     * 
     * 這段主要是在初始化 JsPsych。
     * 當實驗結束後,就執行一個函式
     * 這個函式會執行 `jsPsych.data.displayData();` 指令
     * 在網頁上呈現剛才實驗的數據結果
     */
    var jsPsych = initJsPsych({
      on_finish: function() {
        jsPsych.data.displayData();
      }
    });

    /** 
     * create timeline
     * 
     * 建立一個空的陣列。等等需要的實驗流程資訊會被放到這裡面
     */
    var timeline = [];

    /** 
     * preload images
     * 
     * 先宣告等等在實驗中會用到的實驗素材圖片路徑
     * 在實驗開始前,先預下載到網頁上,這樣在正式實驗時就可快速顯時圖片出來
     * 最後將這個預下載的實驗流程,放進 timeline 陣列裡面
     * 
     * jsPsychPreload 是 jspsych 提供的功能
     * 可以預先載入檔案素材 
     * https://www.jspsych.org/7.3/plugins/preload/
     */
    var preload = {
      type: jsPsychPreload,
      images: ['img/blue.png', 'img/orange.png']
    };
    timeline.push(preload);

    /** 
     * define welcome message trial
     * 
     * 歡迎資訊。慣例在實驗開始前,會先跟受試者打聲招呼
     * 說謝謝你來當白老鼠(誤)來參與實驗
     * 
     * jsPsychHtmlKeyboardResponse 是 jspsych 提供的功能
     * 可以紀錄鍵盤產生的回應
     * https://www.jspsych.org/7.3/plugins/html-keyboard-response/
     */
    var welcome = {
      type: jsPsychHtmlKeyboardResponse,
      stimulus: "Welcome to the experiment. Press any key to begin."
    };
    timeline.push(welcome);

    /** 
     * define instructions trial
     *  
     * 指導語
     * 主試者跟受試者說,等等實驗要做什麼事情、以及注意事項
     */
    var instructions = {
      type: jsPsychHtmlKeyboardResponse,
      stimulus: `
        <p>In this experiment, a circle will appear in the center 
        of the screen.</p><p>If the circle is <strong>blue</strong>, 
        press the letter F on the keyboard as fast as you can.</p>
        <p>If the circle is <strong>orange</strong>, press the letter J 
        as fast as you can.</p>
        <div style='width: 700px;'>
        <div style='float: left;'><img src='img/blue.png'></img>
        <p class='small'><strong>Press the F key</strong></p></div>
        <div style='float: right;'><img src='img/orange.png'></img>
        <p class='small'><strong>Press the J key</strong></p></div>
        </div>
        <p>Press any key to begin.</p>
      `,
      post_trial_gap: 2000
    };
    timeline.push(instructions);

    /** 
     * define trial stimuli array for timeline variables
     * 
     * 定義等等的刺激材料,對應的正確反應按鍵是什麼
     * 藍色的圖片,要按 f 才正確
     * 橘色的圖片,要按 j 才正確
     */
    var test_stimuli = [
      { stimulus: "img/blue.png",  correct_response: 'f'},
      { stimulus: "img/orange.png",  correct_response: 'j'}
    ];

    /**
     * define fixation and test trials
     * 
     * 設定凝視點,以及嘗試次
     * 
     * 每個嘗試次的凝視階段,會有隨機的呈現時間,從 250ms ~ 2000ms
     * 
     * 嘗試次階段,會把刺激材料呈現出來
     * 並且紀錄受試者按的按鈕,並且確認有沒有答對
     * 
     */
    var fixation = {
      type: jsPsychHtmlKeyboardResponse,
      stimulus: '<div style="font-size:60px;">+</div>',
      choices: "NO_KEYS",
      trial_duration: function(){
        return jsPsych.randomization.sampleWithoutReplacement([250, 500, 750, 1000, 1250, 1500, 1750, 2000], 1)[0];
      },
      data: {
        task: 'fixation'
      }
    };

    var test = {
      type: jsPsychImageKeyboardResponse,
      stimulus: jsPsych.timelineVariable('stimulus'),
      choices: ['f', 'j'],
      data: {
        task: 'response',
        correct_response: jsPsych.timelineVariable('correct_response')
      },
      on_finish: function(data){
        data.correct = jsPsych.pluginAPI.compareKeys(data.response, data.correct_response);
      }
    };

    /** 
     * define test procedure
     * 
     * 定義在測試階段資料中,想設定的資訊
     * 
     * timeline: 這個階段想要有哪些次要階段
     * timeline_variables: 這個階段想引入哪些刺激材料
     * repetitions: 想要重複的次數
     * randomize_order: 是否要隨機分派呈現順序
     *
     * 由於這是 demo 實驗,所以沒有正式階段
     */
    var test_procedure = {
      timeline: [fixation, test],
      timeline_variables: test_stimuli,
      repetitions: 5,
      randomize_order: true
    };
    timeline.push(test_procedure);

    /**
     * define debrief
     * 
     * 這段是實驗執行完成後,會先呈現一些簡單的結果數據給受試者看
     * 
     * trials: 把被標記為 response 的 task 資料給撈出來
     * correct_trials: 把作答是正確的 trials 資料給撈出來
     * accuracy: 計算受試者在實驗中的整體作答平均正確率
     * rt: 計算受試者在實驗中的整體作答平均反應時間
     */
    var debrief_block = {
      type: jsPsychHtmlKeyboardResponse,
      stimulus: function() {

        var trials = jsPsych.data.get().filter({task: 'response'});
        var correct_trials = trials.filter({correct: true});
        var accuracy = Math.round(correct_trials.count() / trials.count() * 100);
        var rt = Math.round(correct_trials.select('rt').mean());

        return `<p>You responded correctly on ${accuracy}% of the trials.</p>
          <p>Your average response time was ${rt}ms.</p>
          <p>Press any key to complete the experiment. Thank you!</p>`;

      }
    };
    timeline.push(debrief_block);

    /** 
     * 這段是實際執行實驗的程式碼
     * 前面的程式碼都只是在設定而已,還沒有正式執行
     * 等到這一行時才會開始執行
     */
    jsPsych.run(timeline);

  </script>
</html>

小結

今天簡單介紹的心理學實驗流程,以及 jspsych demo 的程式註解。明天來談一下怎麼解讀實驗的數據。


上一篇
[給心理人的前端網頁開發] 22 關卡三:網路實驗 - jsPsych Demo Simple Reaction Time Task
下一篇
[給心理人的前端網頁開發] 24 關卡三:網路實驗 - jsPsych Demo Simple Reaction Time Task 資料解讀
系列文
給心理人的前端網頁開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言